package se.webbzon.boltzmann.battle.object.status;

import java.awt.Color;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import javax.media.j3d.Transform3D;
import javax.vecmath.Vector3d;

import se.webbzon.oschi01.friendly.Friendly;
import se.webbzon.oschi01.worldobject.appearance.Appearance3D;
import se.webbzon.oschi01.worldobject.appearance.GroupAppearance3D;
import se.webbzon.oschi01.worldobject.appearance.SimpleAppearance3D;
import se.webbzon.oschi01.worldobject.appearance.XYPlaneAppearance3D;

@Friendly class BattleStatusBarAppearance extends GroupAppearance3D  {

	// The rendering order of the status bar
	private static final int renderingOrder = 2;
	
	// The appearance of the health bar and energy bar
	private final SimpleAppearance3D healthBar, invHealthBar, energyBar, invEnergyBar;
	
	/*============================================================
	Constructors
	============================================================*/
	
	/** Creates a new abstract battle status bar appearance. **/
	public BattleStatusBarAppearance() {
		this(Arrays.asList(new Appearance3D[] {
				new XYPlaneAppearance3D(0,SimpleAppearance3D.TRANSPARENCY,false),
				new XYPlaneAppearance3D(1,SimpleAppearance3D.LAYERS,false),
				new XYPlaneAppearance3D(1,SimpleAppearance3D.LAYERS,false),
				new XYPlaneAppearance3D(1,SimpleAppearance3D.LAYERS,false),
				new XYPlaneAppearance3D(1,SimpleAppearance3D.LAYERS,false)
		}));
	}
	
	/** Creates a new abstract battle status bar appearance from a list of appearances. **/
	private BattleStatusBarAppearance(List<Appearance3D> appearances) {
		super(renderingOrder, GroupAppearance3D.TRANSPARENCY, appearances);
		Iterator<Appearance3D> appearanceIterator = appearances.iterator();
		
		SimpleAppearance3D background = (SimpleAppearance3D) appearanceIterator.next();
		background.setColor(Color.black);
		
		healthBar = (SimpleAppearance3D) appearanceIterator.next();
		healthBar.setColor(Color.green);
		healthBar.setLayer(0, 0, 1);
		
		invHealthBar = (SimpleAppearance3D) appearanceIterator.next();
		invHealthBar.setColor(Color.red);
		invHealthBar.setLayer(0, 0, 1);
		
		energyBar = (SimpleAppearance3D) appearanceIterator.next();
		energyBar.setColor(Color.yellow);
		energyBar.setLayer(0, 0, 1);
		
		invEnergyBar = (SimpleAppearance3D) appearanceIterator.next();
		invEnergyBar.setColor(Color.gray);
		invEnergyBar.setLayer(0, 0, 1);
	}
	
	/*============================================================
	Public Methods
	============================================================*/
	
	/** Returns the health bar appearance associated with this status bar appearance. **/
	public SimpleAppearance3D getHealthBar() {
		return healthBar;
	}
	
	/** Returns the energy bar appearance associated with this status bar appearance. **/
	public SimpleAppearance3D getEnergyBar() {
		return energyBar;
	}
	
	/** Sets the status of this status bar appearance. **/
	public void setStatus(int health, int energy, int maxHealth, int maxEnergy) {
		boolean showEnergy = (maxEnergy > 0);
		setHealth(health,maxHealth,showEnergy);
		setEnergy(energy,maxEnergy);
	}
	
	/*============================================================
	Private Methods
	============================================================*/
	
	/** Sets the health of the health bar. **/
	private void setHealth(int health, int maxHealth, boolean showEnergy) {
		final Transform3D transform = new Transform3D();
		final Vector3d vector = new Vector3d();
		
		// Set the vertical scale and translate the health bar
		double yOffset;
		double yScale;
		if (showEnergy) {
			yOffset = 0.125;
			yScale = 0.70;
		} else {
			yOffset = 0;
			yScale = 0.95;
		}
		
		// Transform health bar
		double q = health / (double) maxHealth;
		double xScale = 0.95 * q;
		double xOffset = -0.95 * (1-q) / 2.0;
		
		vector.set(xOffset,yOffset,0);
		transform.setTranslation(vector);
		vector.set(xScale,yScale,0);
		transform.setScale(vector);
		healthBar.setTransform(transform);
		
		// Transform the inverted health bar
		q = 1 - q;
		xScale = 0.95 * q;
		xOffset = 0.95 * (1-q) / 2.0;
		vector.set(xOffset,yOffset,0);
		transform.setTranslation(vector);
		vector.set(xScale,yScale,0);
		transform.setScale(vector);
		invHealthBar.setTransform(transform);
	}
	
	/** Sets the energy of the energy bar. **/
	private void setEnergy(int energy, int maxEnergy) {
		final Transform3D transform = new Transform3D();
		final Vector3d vector = new Vector3d();
		
		if (maxEnergy == 0) {
			// Hide energy bar
			energyBar.setVisible(false);
			invEnergyBar.setVisible(false);
			
		} else {
			// Transform energy bar
			double q = energy / (double) maxEnergy;
			double xScale = 0.95 * q;
			double xOffset = -0.95 * (1-q) / 2.0;
			vector.set(xOffset,-0.375,0);
			transform.setTranslation(vector);
			vector.set(xScale,0.20,0);
			transform.setScale(vector);
			energyBar.setTransform(transform);
		
			// Transform the inverted energy bar
			q = 1 - q;
			xScale = 0.95 * q;
			xOffset = 0.95 * (1-q) / 2.0;
			vector.set(xOffset,-0.375,0);
			transform.setTranslation(vector);
			vector.set(xScale,0.20,0);
			transform.setScale(vector);
			invEnergyBar.setTransform(transform);
		}
	}

}
